//
// Created by win10 on 24-11-20.
//
//
// Created by win10 on 2024/10/18.
//
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
//第一步 创建链表的结构
//1.头节点  包含了一个链表长度 一个指针域 结构体来构建
typedef struct Head{
int length;
//头指针，指向链表的第一个节点
struct Node*head;//思考一个问题 头指针的指针类型是什么？
  //指针指向的是下一个节点，不是节点中的数据域  指针类型和节点数据类型相同
}Linklist;

//2.节点 结构体 包含了数据域 指针域
typedef struct Node{
  int data;
 struct Node * next;
}Node;

//第三步 初始化链表
void initList(Linklist *list){
  list->head = NULL;//头指针 变成 空域 和后面的节点进行切割
  list->length = 0;//表长归零
}

//第四步 创建一个节点
//在一个内存地址上 去创建一个节点 ==》 农地开荒 先确定好 在哪一块土地里面种树
//如何去确定内存大小呢？==》malloc进行动态的空间分配
createNode(int data){//参数在数据域里传入的数据 || 返回值类型 指针变量 代表一个内存地址

  Node *newNode = (Node *)malloc(sizeof(Node));//malloc（）函数里面的参数 需要分配的空间大小
  newNode->data = data;                         //newNode指针去接收新的地址
  //鲁棒性判断 当前内存空间当中是否还有空间剩余
  if(newNode == NULL){
    return NULL;//内存消耗完了 不能再创建 新的节点了
   }
   newNode->data= data;
   newNode->next = NULL;
   return newNode;
}
//销毁一个链表 每一个节点 占用一定的存储空间
//链表使用完毕之后 整个链表所占用的空间 释放出来 free
void destroyList(Linklist *list) {
  //1。鲁棒性的判断
  if(list==NULL){
    return;
  }
  //2.创建指针 遍历整个链表
  Node *temp=list->head;
  while(temp!=NULL) {
    Node *next=temp->next;
    //3.释放当前 temp指针所指向的位置
    free(temp);
    temp=next;
  }
  //3.头节点进行操作
  list->head = NULL;
  list->length = 0;
}

bool insertHead(Linklist *list, int data,int pos){
  //判断 插入的位置是不是正确的
  if(pos<0 || pos>list->length){
    return false;
  }
  //插入一个节点之前先要 创建一个节点
  Node *newNode = createNode(data);
  //3.判断插入的位置
  if(pos==0)//3.1插入到头节点之后
    {
    //原来头节点的指针域的地址赋值给新创建出来的节点的指针域
    newNode->next = list->head;
    //再把新创建出来的节点的地址赋值给头节点的指针域
    list->head = newNode;
    }else{//3.2. 插入到任意节点后面
     Node *current = list->head;//一号节点的地址
     for(int i=0;i<pos-1;i++){
              current = current->next;
     }
     newNode=current->next ;
     current->next = newNode;

    }
    //4.表长加一并返回值
    list->length++;
    return true;
}

//删除链表当中指定的一个值？ 对整个链表进行一次遍历
void deleteHead(Linklist *list,int val) {
  //1.创建两个 指针 整个链表进行遍历
  Node *current=list->head;
  Node *previous=NULL;
  //2.通过遍历链表 找到需要删除的值
  while(current!=NULL &&current->data!=val){
    previous=current;
    current=current->next;
  }
  //3.鲁棒性的判断
  if(current!=NULL) {
    printf("value not found");
    return ;
  }
  //4.删除值
  //4.1在头节点
  if(previous==NULL) {
    list->head = list->head->next;
  }
  //4.2不在头节点
  else {
    previous->next = current->next;
  }
  //5.存储空间的释放 链表长度减一
  free(current);
  list->length--;
}
void printList(Linklist *list) {
  //创建指针遍历 链表
  Node *current = list->head;
  while(current!=NULL) {
    printf("%d ",current->data);
  }
}
void product(Linklist *list,int val) {

}
//第二步 新建一个链表
int main(){
  Linklist list;//列表只有一个头节点 后面的节点需要我们自己手动输入
  Linklist *Lhead=&list;//第一个指针的地址
  initList(&list);
//  //手动插入节点
//  Node * new1=createNode(1);
//  Node * new2=createNode(2);
//  Node * new3=createNode(3);
//  //连接这些节点
//  //需要把第一个节点的地址写在头指针的指针域里面
//  Lhead->head = new1;
//  new1->next = new2;
//  new2->next = new3;
//  new3->next = NULL;//意义不是很大
  insertHead(&list,1,0);
  insertHead(&list,1,1);
  insertHead(&list,1,2);

}